package com.studykun.client.ui;

import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.Widget;

import static com.studykun.client.util.StringUtils.*;

public class HiraganaMatchedText extends InlinePanel {
  private String kanji_;
  private String hiragana_;
  public static final char UNICODE_2710 = '✐';
  public static final char UNICODE_2717 = '✗';
  public static final char UNICODE_2713 = '✓';
  
  public HiraganaMatchedText(
      final String hiragana,
      final String kanji) {
    hiragana_ = hiragana;
    kanji_ = kanji;
    this.add(createMatch(""));
  }

  private String buildMask(
      final String answer)
  {
    final String expectedAnswer = kanji_;
    final StringBuilder kanjiMask = new StringBuilder(expectedAnswer);
    final StringBuilder answerMask = new StringBuilder(answer);
    
    for (int i = answerMask.length(); i > 0; --i) {
      for (int j = 0; j < answerMask.length() - i + 1; ++j) {
        int index = kanjiMask.indexOf(answerMask.substring(j, i + j));
        if (index == -1) {
          continue;
        }
        kanjiMask.replace(index, index + i, repeat("✓", i));
        answerMask.replace(j, j + i, repeat("✗", i));
      }
    }
    
    char lastMask = '＿';
    for (int i = 0; i < kanjiMask.length(); ++i) {
      if (kanjiMask.charAt(i) == '＿') {
        kanjiMask.setCharAt(i, lastMask);
      } else if (kanjiMask.charAt(i) != '✓') {
        kanjiMask.setCharAt(i, '✗');
      }
      lastMask = kanjiMask.charAt(i);
    }
    
    return kanjiMask.toString();
  }
  
  private InlineHTML makeSegment(
      final char lastMask,
      final String text)
  {
    final InlineHTML inlineHtml = new InlineHTML(text);
    final Element element = inlineHtml.getElement();
    switch (lastMask) {
    case '✓':
      element.setClassName("correctSegment");
      break;
    case '✗':
      element.setClassName("incorrectSegment");
      break;
    case '✐':
      element.setClassName("incompleteSegment");
      break;
    }
    return inlineHtml;
  }
  
  private Widget createMatch(
      final String answer) {
    final String mask = buildMask(answer);
    
    final InlinePanel inlinePanel = new InlinePanel();
    char lastMask = '\0';
    String currentText = null;
    
    for (int i = 0; i < mask.length(); ++i) {
      final char newMask = mask.charAt(i);
      if (newMask != lastMask) {
        if (currentText != null) {
          inlinePanel.add(makeSegment(lastMask, currentText));
        }
        currentText = "";
      }
      lastMask = newMask;
      currentText += hiragana_.charAt(i);
    }
    
    if (currentText != null) {
      inlinePanel.add(makeSegment(lastMask, currentText));
    }
    
    return inlinePanel;
  }
  
  public void match(
      final String text) {
    this.clear();
    this.add(createMatch(text));
  }
  
  public String hiragana() {
    return hiragana_;
  }

  public String kanji() {
    return kanji_;
  }
}
